home *** CD-ROM | disk | FTP | other *** search
- /* KickLoad.c - Manipulate the Exec Kickstart delta list */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <exec/types.h>
- #include <exec/execbase.h>
- #include <exec/memory.h>
- #include <exec/resident.h>
- #include <proto/exec.h>
-
- static const char _version[] = "$VER: KickLoad 1.0 (19.10.93)";
-
- struct ExecBase **ExecBase = (struct ExecBase **) 0x000004;
-
- FILE *fp;
- char *code;
- unsigned long mem_size;
-
- struct MemList *KickMem, *myMemList;
- long *KickTag, *myTagPtr;
-
- void clean (char *, char *);
- void display_kick (void);
- void clear_kick (void);
- unsigned long getlong (void);
- int load_kick (char *);
- int load_image (char *);
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
- int i;
-
- if (argc < 2) {
- display_kick ();
- }
- else if (strcmp (argv[1], "-clear") == 0) {
- clear_kick ();
- }
- else for (i = 1; i < argc; ++i)
- load_kick (argv[i]);
- }
-
- /*
- * load_kick (fname) - load an executable image and insert it into the
- * Exec KickStart delta list
- *
- */
-
- load_kick (fname)
- char *fname;
- {
- fp = fopen (fname, "r");
- if (fp == NULL) {
- clean ("unable to open %s", fname);
- return (-1);
- }
- if (load_image (fname))
- return (-1);
- fclose (fp);
- fp = NULL;
- /* link into ExecBase data */
- KickMem = (struct MemList *) (*ExecBase)->KickMemPtr;
- KickTag = (long *) (*ExecBase)->KickTagPtr;
- #if 0
- FreeMem (code, mem_size); /* temp */
- printf ("KickLoad: %s test load sucessful\n", fname);
- #else
- Forbid ();
- while (KickMem && KickMem->ml_Node.ln_Succ)
- KickMem = (struct MemList *) KickMem->ml_Node.ln_Succ;
- myMemList->ml_Node.ln_Pred = (struct Node *) KickMem;
- if (KickMem)
- KickMem->ml_Node.ln_Succ = (struct Node *) myMemList;
- else
- (*ExecBase)->KickMemPtr = (APTR) myMemList;
- /* Todo - add TagPtr to tail of TagPtr list */
- if (KickTag)
- myTagPtr[1] = ((long) KickTag) | 0x80000000;
- (*ExecBase)->KickTagPtr = (APTR) myTagPtr;
- (*ExecBase)->KickCheckSum = (APTR) SumKickData ();
- Permit ();
- printf ("KickLoad: %s sucessfully installed\n", fname);
- #endif
- code = NULL;
- return (0);
- }
-
- /*
- * load_image (fname) - load an executable image into memory
- * fname = path to image file
- *
- * outputs:
- * code - address of executable memory + TagPtr + MemList
- * myTagPtr - address of TagPtr table
- * myMemList - address of MemList structure
- *
- * Executable image begins at code; TagPtr is two longwords following
- * the executable image; MemList follows the TagPtr. TagPtr points to
- * the first RomTag found in the image. MemList contains one entry and
- * is the image/TagPtr/MemList data.
- * *** only one RomTag is recognized
- * *** memory is allocated from Chip memory
- * *** [could request DMAable memory for V36 (2.0)
- */
-
- load_image (fname)
- char *fname;
- {
- unsigned long u, getlong ();
- int i, j, k;
- unsigned long *hunk_table;
- unsigned long hunk;
- int hunk_type;
- char *hunk_ptr;
- unsigned long *loc;
- unsigned short *res_ptr;
- unsigned long code_size;
-
- if (getlong () != 1011) { /* Must be HUNK_HEADER */
- clean ("%s is not an image file", fname);
- return (-1);
- }
- if (getlong ()) { /* don't allow resident lib */
- clean ("%s Resident library not allowed", fname);
- return (-1);
- }
- u = getlong (); /* Hunk table size */
- hunk = getlong (); /* first hunk */
- u = getlong (); /* last hunk */
- hunk_table = (long *) calloc (u + 1, sizeof (long));
- if (hunk_table == NULL) {
- clean ("unable to allocate memory for hunk table", NULL);
- return (-1);
- }
- code_size = 0;
- for (i = hunk; i <= u; ++i)
- code_size += hunk_table[i] = getlong () * 4;
- mem_size = code_size + sizeof (struct MemList) + 8 + 8;
- #ifdef MEMF_24BITDMA
- code = (char *) AllocMem (mem_size, MEMF_CLEAR | MEMF_24BITDMA);
- #else
- code = (char *) AllocMem (mem_size, MEMF_CLEAR | MEMF_CHIP);
- #endif
- if (code == NULL) {
- clean ("unable to allocate memory for image", NULL);
- free (hunk_table);
- return (-1);
- }
- /* Leave 8 byte buffer from beginning of allocated memory
- * Memory List
- * RomTag pointer array
- * resident module data
- */
- myMemList = (struct MemList *) (code + 8);
- myTagPtr = (unsigned long *) (myMemList + 1);
- code = (char *) (myTagPtr + 2);
- for (i = hunk, j = 0; i <= u; ++i) {
- k = hunk_table[i];
- hunk_table[i] = (long) (code + j);
- j += k;
- }
- do {
- switch (hunk_type = getlong ()) {
- case 1001: /* HUNK_CODE */
- case 1002: /* HUNK_DATA */
- case 1003: /* HUNK_BSS */
- hunk_ptr = (char *) hunk_table[hunk++];
- u = getlong (); /* code length */
- if (hunk_type != 1003 && u)
- fread (hunk_ptr, u, 4, fp);
- break;
- case 1004: /* HUNK_RELOC32 */
- while (i = getlong ()) { /* get # refs */
- j = getlong (); /* hunk # */
- /* tpdo - validate hunk # */
- j = hunk_table[j];
- while (i--) {
- u = getlong (); /* offset */
- loc = (long *) (hunk_ptr + u);
- *loc += (unsigned long) j;
- }
- }
- break;
- case 1010:
- break;
- case 0xffffffff:
- break;
- default:
- clean ("Can't handle hunk type %d", (char *) hunk_type);
- free (hunk_table);
- return (-1);
- break;
- }
- } while (hunk_type != 0xffffffff);
- free (hunk_table);
- /* make MemList structure and TagPtr table */
- res_ptr = (unsigned short *) code; /* search for ROMTAG */
- while ((char *) res_ptr < code + code_size) {
- if (*res_ptr == RTC_MATCHWORD)
- break;
- ++res_ptr;
- }
- if (*res_ptr != RTC_MATCHWORD)
- res_ptr = 0; /* didn't find ROMTAG */
- /* should abort if no ROMTAG found */
- /* also should verify ROMTAG: rt_MatchTag == res_ptr,
- rt_EndSkip <= code + code_size */
- myTagPtr[0] = (unsigned long) res_ptr;
- myTagPtr[1] = 0;
- myMemList->ml_Node.ln_Succ = NULL;
- myMemList->ml_Node.ln_Pred = NULL;
- myMemList->ml_Node.ln_Type = NT_MEMORY;
- myMemList->ml_Node.ln_Pri = 0;
- /* use ROMTAG name as MemList node name */
- /* todo - use fname as the MemList node name? */
- if (res_ptr)
- myMemList->ml_Node.ln_Name = ((struct Resident *) res_ptr)->rt_Name;
- myMemList->ml_NumEntries = 1;
- myMemList->ml_ME[0].me_Un.meu_Addr = (APTR) ((char *) myMemList - 8);
- myMemList->ml_ME[0].me_Length = mem_size;
- return (0);
- }
-
- unsigned long getlong ()
- {
- unsigned long u;
-
- if (fread ((char *) &u, 4, 1, fp) != 1)
- return (0xffffffff);
- return (u);
- }
-
- void clean (text, arg)
- char *text, *arg;
- {
- printf ("KickLoad: ");
- printf (text, arg);
- printf ("\n");
- if (fp) {
- fclose (fp);
- fp = NULL;
- }
- if (code) {
- FreeMem (code, mem_size);
- code = NULL;
- }
- }
-
- /*
- * display_kick - display Exec KickStart delta list
- *
- */
-
- void display_kick ()
- {
- int i, l;
- struct Resident *res_ptr;
- char *start_quote, *end_quote;
-
- KickMem = (struct MemList *) (*ExecBase)->KickMemPtr;
- KickTag = (long *) (*ExecBase)->KickTagPtr;
- printf ("KickMemPtr = $%08x\n", KickMem);
- while (KickMem) {
- printf (" MemList = $%08x \"%s\"\n", KickMem,
- KickMem->ml_Node.ln_Name ? KickMem->ml_Node.ln_Name :
- "*unnamed*");
- for (i = 0; i < KickMem->ml_NumEntries; ++i) {
- printf (" [%d] Addr = $%08x, Length = $%x\n",
- i, KickMem->ml_ME[i].me_Un.meu_Addr,
- KickMem->ml_ME[i].me_Length);
- }
- KickMem = (struct MemList *) KickMem->ml_Node.ln_Succ;
- }
- printf ("KickTagPtr = $%08x\n", KickTag);
- while (KickTag) {
- printf (" RomTags at $%08x:\n", KickTag);
- i = 0;
- while (KickTag[i] > 0) {
- res_ptr = (struct Resident *) KickTag[i];
- printf (" [%d] -> $%08x", i++, res_ptr);
- if (res_ptr == NULL) {
- printf (" <No ROMTAG>\n");
- continue;
- }
- start_quote = "\"";
- end_quote = "\"\n";
- if (res_ptr->rt_IdString && (l = strlen (res_ptr->rt_IdString))) {
- if (res_ptr->rt_IdString[l-1] == '\n')
- start_quote = end_quote = "";
- }
- printf (" \"%s\" Type=%d Pri=%d Id=%s%s%s",
- res_ptr->rt_Name,
- res_ptr->rt_Type, res_ptr->rt_Pri,
- start_quote, res_ptr->rt_IdString, end_quote);
- if (res_ptr->rt_MatchWord != RTC_MATCHWORD)
- printf ("\t**** Invalid MatchWord: $%04x\n",
- res_ptr->rt_MatchWord);
- }
- KickTag = (long *) (KickTag[i] & 0x7fffffff);
- }
- }
-
- /*
- *
- * clear_kick - remove the Exec Kickstart delta list
- *
- * Should add optional arguement to specify which entry to remove.
- * currently the entire list is removed.
- *
- */
-
- void clear_kick ()
- {
- int i;
-
- KickMem = (struct MemList *) (*ExecBase)->KickMemPtr;
- KickTag = (long *) (*ExecBase)->KickTagPtr;
- printf ("KickMemPtr = $%08x\n", KickMem);
- while (KickMem) {
- printf (" MemList = $%08x \"%s\"\n", KickMem,
- KickMem->ml_Node.ln_Name ? KickMem->ml_Node.ln_Name :
- "*unnamed*");
- for (i = 0; i < KickMem->ml_NumEntries; ++i) {
- printf (" [%d] Addr = $%08x, Length = $%x\n",
- i, KickMem->ml_ME[i].me_Un.meu_Addr,
- KickMem->ml_ME[i].me_Length);
- }
- #if 0 /* don't deallocate memory - it may still be in use */
- Forbid ();
- for (i = 0; i < KickMem->ml_NumEntries; ++i) {
- FreeMem (KickMem->ml_ME[i].me_Un.meu_Addr,
- KickMem->ml_ME[i].me_Length);
- }
- Permit ();
- #endif
- printf (" .. Removed\n");
- KickMem = (struct MemList *) KickMem->ml_Node.ln_Succ;
- }
- Forbid ();
- (*ExecBase)->KickMemPtr = NULL;
- (*ExecBase)->KickTagPtr = NULL;
-
- }
-